package net.wangds.auth.user.comp;

import net.wangds.jdbc.comp.jdbc.JdbcComp;
import net.wangds.utils.JsonUtils;
import net.wangds.auth.account.entity.GeneralAccountUserRef;
import net.wangds.auth.account.repo.rdbms.AccountUserRefJpaRepo;
import net.wangds.auth.department.entity.GeneralDepartmentUserRef;
import net.wangds.auth.department.repo.rdbms.DepartmentUserRefRepo;
import net.wangds.auth.job.entity.GeneralJobUserRef;
import net.wangds.auth.job.repo.rdbms.JobUserRefRepo;
import net.wangds.auth.module.*;
import net.wangds.auth.role.comp.GeneralRoleComp;
import net.wangds.auth.role.repo.rdbms.RoleJpaRepo;
import net.wangds.auth.user.entity.*;
import net.wangds.auth.user.repo.rdbms.UserJpaRepo;
import net.wangds.auth.user.repo.rdbms.UserRoleRefJpaRepo;
import net.wangds.data.DisableEnum;
import net.wangds.data.RemovedEnum;
import net.wangds.jpa.comp.AbstractRemovedComp;
import net.wangds.log.helper.LogHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Component
public class GeneralUserComp extends AbstractRemovedComp<GeneralUserEntity> {

    private final UserJpaRepo mmRepoUsr;
    private final UserRoleRefJpaRepo mmRepoUsrRole;
    private final DepartmentUserRefRepo mmJpaDeptUserRef;

    @Autowired
    private RoleJpaRepo mmRepoRole;

    @Autowired
    private GeneralRoleComp mmCmpRole;

    @Autowired
    private AccountUserRefJpaRepo mmJpaAccUsrRef;


    @Autowired
    private JobUserRefRepo mmJpaJobUsrRef;

    @Autowired
    private UserRoleRefJpaRepo mmJpaRoleUserRef;


    @Autowired
    private JdbcComp mmJdbc;

    /**
     * 获取微信应用id的组件.
     */
    @Autowired
    private WeiXinAgentIdSupplier mmSupWxAgentId;


    @Autowired
    public GeneralUserComp(UserJpaRepo repo
            , UserRoleRefJpaRepo repoUserRole
            ,DepartmentUserRefRepo repoDeptUsrRef
    ){
        super(repo);
        mmRepoUsr = repo;
        mmRepoUsrRole = repoUserRole;
        mmJpaDeptUserRef = repoDeptUsrRef;
    }

    /**
     * 获得用户的角色列表.
     * @param user 用户.
     * @return 角色列表.
     */
    public List<Role> loadUserRoles(User user){
        if(user==null){
            return Collections.emptyList();
        }

        List<GeneralUserRoleRef> list = mmRepoUsrRole.findByUserIdAndDisableAndRemoved(user.getId(), DisableEnum.NORMAL, RemovedEnum.NORMAL);

        List<Role> res = new ArrayList<>(list.size());

        list.forEach(r-> mmRepoRole.findByIdAndRemoved(r.getRoleId(), RemovedEnum.NORMAL).ifPresent(res::add));

        return res;
    }


    /**
     * 关联账户和邮件.
     * @param account 账户.
     * @param email email.
     */
    public void createEmailUser(Account account, String email){

    }

    /**
     * 关联短信验证用户.
     * @param account 账户.
     * @param mobile 手机号.
     */
    public SmsUserEntity createSmsUser(Account account, String mobile){
        return null;
    }

    public AndroidUserEntity createAndroidUser(Account account, String deviceId){
        return null;
    }

    public IphoneUserEntity createIphoneUesr(Account account, String deviceId){
        return null;
    }

    public WexinUserEntity createWeixinUserWithOpenId(Account account, String agentId, String openId){
        return null;
    }

    public WexinUserEntity createWeixinUserWithUnionId(Account account, String agentId, String unionId){
        return null;
    }



    public void ref2Account(User user, Account account){
        String uid = user.getId();
        String accountId = account.getId();
        GeneralAccountUserRef ref = mmJpaAccUsrRef.findByAccountIdAndUserId(accountId, uid)
                .orElseGet(() -> GeneralAccountUserRef.builder().accountId(accountId).userId(uid).build());
        ref.setRemoved(RemovedEnum.NORMAL);
        ref.setDisable(DisableEnum.NORMAL);
        LogHelper.dev(()->"关联用户和帐户："+ JsonUtils.toJsonStr(ref));
        mmJpaAccUsrRef.saveAndFlush(ref);
    }

    public void unref2Account(User user, Account account){

        String uid = user.getId();
        String accountId = account.getId();
        mmJpaAccUsrRef.findByAccountIdAndUserId(accountId, uid).ifPresent(ref->{
            mmJpaAccUsrRef.delete(ref);
            mmJpaAccUsrRef.flush();
        });
    }

    public void ref2Department(User user, Department department){
        String uid = user.getId();
        String deptId = department.getId();
        GeneralDepartmentUserRef ref = mmJpaDeptUserRef.findByDeptIdAndUserId(uid, deptId).orElseGet(
                ()-> GeneralDepartmentUserRef.builder().userId(uid).deptId(deptId).build()
        );
        ref.setRemoved(RemovedEnum.NORMAL);
        mmJpaDeptUserRef.saveAndFlush(ref);
    }

    public void unref2Department(User user, Department department){

        String uid = user.getId();
        String deptId = department.getId();

        mmJpaDeptUserRef.findByDeptIdAndUserId(uid, deptId).ifPresent(ref->{
            mmJpaDeptUserRef.delete(ref);
            mmJpaDeptUserRef.flush();
        });
    }

    public void ref2Job(User user, Job job){
        String uid = user.getId();
        String jobId = job.getId();


        GeneralJobUserRef ref = mmJpaJobUsrRef.findByJobIdAndUserId(jobId,uid).orElseGet(
                ()-> GeneralJobUserRef.builder().userId(uid).jobId(jobId).build()
        );
        ref.setRemoved(RemovedEnum.NORMAL);
        mmJpaJobUsrRef.saveAndFlush(ref);

    }
    public void unref2Job(User user, Job job){
        String uid = user.getId();
        String jobId = job.getId();

        mmJpaJobUsrRef.findByJobIdAndUserId(jobId, uid).ifPresent(ref->{
            mmJpaJobUsrRef.delete(ref);
            mmJpaJobUsrRef.flush();
        });
    }


    public void ref2Role(User user, Role role) {
        String uid = user.getId();
        String roleId = role.getId();

        GeneralUserRoleRef ref = mmJpaRoleUserRef.findByUserIdAndRoleId(uid, roleId).orElseGet(
                () -> GeneralUserRoleRef.builder().userId(uid).roleId(roleId).build()
        );
        ref.setRemoved(RemovedEnum.NORMAL);
        ref.setDisable(DisableEnum.NORMAL);
        mmJpaRoleUserRef.saveAndFlush(ref);

    }

    public void unref2Role(User user, Role role) {
        String uid = user.getId();
        String roleId = role.getId();

        mmJpaRoleUserRef.findByUserIdAndRoleId(uid, roleId).ifPresent(ref->{
            mmJpaRoleUserRef.delete(ref);
            mmJpaRoleUserRef.flush();
        });

    }


    /**
     * 分页查询例外用户id列表之外的用户.
     * @param exceptUids 例外用户id列表.
     * @param removed 是否删除.
     * @param pr 分页信息.
     * @return 查询结果.
     */
    public Page<User> selectUsersExcept(List<String> exceptUids, RemovedEnum removed, PageRequest pr) {
        if(exceptUids.isEmpty()){
            exceptUids.add("");
        }
        return mmRepoUsr.findByIdNotInAndRemoved(exceptUids, removed, pr);
    }

    public List<GeneralDepartmentUserRef> findDepartmentUserRef(GeneralUserEntity user) {
        return mmJpaDeptUserRef.findByUserIdAndRemoved(user.getId(), RemovedEnum.NORMAL);
    }

    public List<GeneralJobUserRef> findJobUserRef(GeneralUserEntity user) {
        return mmJpaJobUsrRef.findByUserIdAndRemoved(user.getId(), RemovedEnum.NORMAL);
    }

    @Override
    public Page<GeneralUserEntity> findByKeywords(String keywords, Pageable paging) {
        String sql = "select t1.id, t1.removed, t1.ctm, t1.birthday_tm, t1.gender, t1.id_card_no, t1.id_card_type, t1.lastname,\n" +
                "t1.name, t1.phone, t1.user_name, t1.user_owner from auth_user t1\n" +
                "where (t1.id_card_no regexp ? or t1.name regexp ? or t1.lastname regexp ?\n" +
                " or t1.user_name regexp ? or t1.phone regexp ?) and t1.removed = 0";
        LogHelper.dev(sql);
        return mmJdbc.executeQuery(sql, new Object[]{keywords, keywords, keywords,keywords,keywords}, paging, GeneralUserEntity.class);
    }
}
